/*
 *Copyright (c) 2024 Black Sesame Technologies
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
*/


#include "../library/printf_inc.h" //use related path
#include "../library/utility_lite.h" 

#include "RegBase.h"
#include "IntNum.h"
#include "../library/RegTest.h" 
#include "sw_crm_reg.h"
#include "../modules/r5_clk/r5_clk.h"

//============================================================================================
#define VERSION_SECTION(label, value)  #label ":" value
#define VERSION_INFO(major, minor, patch, postfix) "\"version details\":\"" VERSION_SECTION(Major, major) "," VERSION_SECTION(Minor, minor) "," VERSION_SECTION(Patch, patch) "," VERSION_SECTION(Postfix, postfix) "," VERSION_SECTION(Date, __DATE__) "," VERSION_SECTION(Time, __TIME__) "\""
#define VERSION_STRING(major, minor, patch, postfix) "\"version\":\"v" major "." minor "." patch "-" postfix \
                                                           " "__DATE__                                                                 \
                                                           " "__TIME__                                                                 \
                                                           "\""
#define PRODUCT_NAME(pname)  "\"product\":" #pname 
#define MAN_NAME(mname)      "\"manufacturer\":" #mname

#define ADD_VER_INFO(mname, pname, major, minor, patch, postfix)                                \
const char s_bst_ver_string[80] = VERSION_STRING(#major, #minor, #patch, #postfix);\
const char s_bst_pro_name[32] = PRODUCT_NAME(pname);\
const char s_bst_man_name[32] = MAN_NAME(mname);\
const char s_bst_ver_info[128] = VERSION_INFO(#major, #minor, #patch, #postfix); 
ADD_VER_INFO("BST", "sw-rel-c1200",1,0,0,2024build)
//============================================================================================


static unsigned int sPrtBase = 0;
#define UART_PRINT_BASE sPrtBase
//#define UART_PRINT_BASE UART1_BASE_ADDR
#define TXD0READY   (1<<6)
#define RXD0READY   (1)

#define UART_PRINT_REG_DLL    (   UART_PRINT_BASE + 0x0   )
#define UART_PRINT_REG_THR    (   UART_PRINT_BASE + 0x0   )
#define UART_PRINT_REG_RBR    (   UART_PRINT_BASE + 0x0   )
#define UART_PRINT_REG_DLH    (   UART_PRINT_BASE + 0x4   )
#define UART_PRINT_REG_LCR    (   UART_PRINT_BASE + 0xC   )
#define UART_PRINT_REG_MCR    (   UART_PRINT_BASE + 0x10  )
#define UART_PRINT_REG_LSR    (   UART_PRINT_BASE + 0x14  )
#define UART_PRINT_REG_DLF    (   UART_PRINT_BASE + 0xC0  )

extern void msgbx_node_isr_handle(void *param);
void msgbox_node_isr_handle(unsigned int param)
{
	u32 int_num = (u32)param;
	msgbx_node_isr_handle((void *)int_num);
}

IRQ_DEFINE(SW_INTR_MSGBOX_INTR0, msgbox_node_isr_handle, SW_INTR_MSGBOX_INTR0, "irq msgbox0 isr", ISR_ATTR_CORE0 | ISR_ATTR_SWITCH | ISR_ATTR_LEVEL);
IRQ_DEFINE(SW_INTR_MSGBOX_INTR1, msgbox_node_isr_handle, SW_INTR_MSGBOX_INTR1, "irq msgbox1 isr", ISR_ATTR_CORE0 | ISR_ATTR_SWITCH | ISR_ATTR_LEVEL);
IRQ_DEFINE(SW_INTR_MSGBOX_INTR2, msgbox_node_isr_handle, SW_INTR_MSGBOX_INTR2, "irq msgbox2 isr", ISR_ATTR_CORE0 | ISR_ATTR_SWITCH | ISR_ATTR_LEVEL);
IRQ_DEFINE(SW_INTR_MSGBOX_INTR3, msgbox_node_isr_handle, SW_INTR_MSGBOX_INTR3, "irq msgbox3 isr", ISR_ATTR_CORE0 | ISR_ATTR_SWITCH | ISR_ATTR_LEVEL);

/////////////////////////////////////clock & sharepin////////////////////////////////////////


void putc_user(unsigned char c)
{
    #ifdef UART_DEBUG_RT2
    while (!(REG32_READ(UART_PRINT_REG_LSR) & TXD0READY)); //bit set means tx is empty
    
    //UTXH0 = c;
    REG32_WRITE(UART_PRINT_REG_THR, c);

    #endif

    //rx, tx FIFO status @USR register
}

void putstr(char* str)
{
    int i = 0;
    while(str[i] != 0){
        putc_user(str[i]);
        i++;
    }
    //rx, tx FIFO status @USR register
}

unsigned char getc_user(void)
{
     unsigned char c;
    while (!(REG32_READ(UART_PRINT_REG_LSR) & RXD0READY));
    
    //UTXH0 = c;
    c = (unsigned char)(REG32_READ(UART_PRINT_REG_RBR));

    //rx, tx FIFO status @USR register
    return c;
}


int getc_nb(unsigned char *c,unsigned int delayLoop)
{
    while(1){
        if (REG32_READ(UART_PRINT_REG_LSR) & RXD0READY){
            break;
        }
        
        if (delayLoop--){
            delaySoft(1);
            continue;
        }        
        return -1;
    }    
    
    *c = (unsigned char)(REG32_READ(UART_PRINT_REG_RBR));    
    return 0;
}


unsigned char getc_unblock(void)
{
    unsigned char c;
    if (!(REG32_READ(UART_PRINT_REG_LSR) & RXD0READY)){
		return 0;
	}
    
    //UTXH0 = c;
    c = (unsigned char)(REG32_READ(UART_PRINT_REG_RBR));

    //rx, tx FIFO status @USR register
    return c;
}


enum{
    BUAD_RATE_ZEBU,
    BUAD_RATE_38400    ,
    BUAD_RATE_115200   ,
    BUAD_RATE_230400   ,
    BUAD_RATE_460800   ,
    BUAD_RATE_921600   ,
    BUAD_RATE_1000000  ,
    BUAD_RATE_1500000  ,
    BUAD_RATE_2000000  ,
    BUAD_RATE_3000000  ,
    BUAD_RATE_4000000  ,
    BUAD_RATE_5000000  ,
    BUAD_RATE_6250000  ,
    BUAD_RATE_8000000  ,
    BUAD_RATE_9000000  ,
    BUAD_RATE_9500000  ,
    BUAD_RATE_10000000 ,
    BUAD_RATE_12000000 ,
    BUAD_RATE_12500000 ,
};

#define BUAD_RATE_MAIN_CLK_25M  0
#define BUAD_RATE_MAIN_CLK_200M 1

void uart_print_init(unsigned int buad, unsigned int port , unsigned int main_clk) 
{   
    sPrtBase = port;

	REG32_WRITE(UART_PRINT_REG_MCR, 0);//disable flow ctrl
	REG32_WRITE(UART_PRINT_REG_MCR, (REG32_READ(UART_PRINT_REG_MCR)|(0x1<<1)));//clear rts
	
	REG32_WRITE(UART_PRINT_REG_LCR, (REG32_READ(UART_PRINT_REG_LCR)|(0x1<<7))); //enable access DLL & DLH

    if(main_clk == BUAD_RATE_MAIN_CLK_25M)
    {
        // sf_uart_wclk_sel , 25mhz
        REG_BIT_CLEAR32(0xc175f000 + 0x8 , BIT1);

        //rt_uart_wclk_sel ,25mhz
        REG_BIT_CLEAR32(0xD0000000 + 0x18 , BIT15);
        REG_BIT_CLEAR32(0xD0020000 + 0x18 , BIT15);
    }
    else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
    {
        //sf_uart_wclk_sel , 200mhz
        REG_BIT_SET32(0xc175f000 + 0x8 , BIT1);

        //rt_uart_wclk_sel ,200mhz
        REG_BIT_SET32(0xD0000000 + 0x18 , BIT15);
        REG_BIT_SET32(0xD0020000 + 0x18 , BIT15);
    }
	
    if (buad == BUAD_RATE_ZEBU)
    {
        REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
    }
    else if(buad == BUAD_RATE_38400)//25mhz
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 40); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 0x2c); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 325); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 33); //fractional part
        }
    }
    else if(buad == BUAD_RATE_115200)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 13); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 36); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 108); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 32); //fractional part
        }
    }
    else if(buad == BUAD_RATE_230400)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 6); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 50); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 54); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 16); //fractional part
        }
    }
    else if(buad == BUAD_RATE_460800)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 3); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 25); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 27); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 8); //fractional part
        }
    }
    else if(buad == BUAD_RATE_921600)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 44); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 13); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 36); //fractional part
        }
    }
    else if(buad == BUAD_RATE_1000000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 36); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 12); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 32); //fractional part
        }
    }
    else if(buad == BUAD_RATE_1500000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 2); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 8); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 21); //fractional part
        }
    }
    else if(buad == BUAD_RATE_5000000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 2); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 32); //fractional part
        }

    }
    else if(buad == BUAD_RATE_6250000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 2); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 0); //fractional part
        }
    }
    else if(buad == BUAD_RATE_8000000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 36); //fractional part
        }
    }
    else if(buad == BUAD_RATE_9000000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 24); //fractional part
        }
    }
    else if(buad == BUAD_RATE_9500000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 20); //fractional part
        }
    }
    else if(buad == BUAD_RATE_10000000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 16); //fractional part
        }
    }
    else if(buad == BUAD_RATE_12000000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 2); //fractional part
        }
    }
    else if(buad == BUAD_RATE_12500000)
    {         
        if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 1); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0x0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 0); //fractional part
        }
    }
    else
    {//38400
        if(main_clk == BUAD_RATE_MAIN_CLK_25M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 40); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 0x2c); //fractional part
        }
        else if(main_clk == BUAD_RATE_MAIN_CLK_200M)
        {
            REG32_WRITE(UART_PRINT_REG_DLL, 325); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLH, 0); //set baud rate
            REG32_WRITE(UART_PRINT_REG_DLF, 33); //fractional part
        }
    }

	REG32_WRITE(UART_PRINT_REG_LCR, ( REG32_READ(UART_PRINT_REG_LCR)&(~(0x1<<7)) ) ); //clear DLAB bit
	 
	REG32_WRITE(UART_PRINT_REG_LCR, REG32_READ(UART_PRINT_REG_LCR)|(0x3)); //set data length to 8 bit, 1 stop bit,no parity
	
	
	delaySoft(10);	
}




void prj_logo(void){
    putc_user('\r');
    putc_user('\n');
    putc_user('s');
    putc_user('w');
    putc_user('i');
    putc_user('t');
    putc_user('c');
    putc_user('h');
    putc_user('R');
    putc_user('5');
    putc_user('>');
}


void r5AsynAbt_open (void)
{
    asm("mrs  R1,CPSR_all");
    asm("BIC  R1,#0x100");
    asm("msr  CPSR_x,R1");    
}

void r5AsynAbt_close (void)
{
    asm("MRS  R1,CPSR_all");
    asm("ORR  R1,#0x100");
    asm("MSR  CPSR_x,R1");  
}

void r5intr_open (void)
{
    asm("MRS  R1,CPSR");
    asm("BIC  R1,#0xC0");
    asm("MSR  CPSR,R1");    
}

void r5intr_close (void)
{
    asm("MRS  R1,CPSR");
    asm("ORR  R1,#0xC0");
    asm("MSR  CPSR,R1");  
}

extern unsigned long __section_irq_table_start;
extern unsigned long __section_irq_table_end;
extern unsigned long __section_fiq_table_start;
extern unsigned long __section_fiq_table_end;

#define NO_ISR 0xfff0ff
static int sIrqTab[IRQ_SWITCH_TOTAL_CNT];
static int sFiqTab[FIQ_SWITCH_TOTAL_CNT];
volatile int isr_init_flag = 0;

/*
1 = cpu 0
2 = cpu 1
*/
unsigned int cpu_getIntrIdx(void){ 
    unsigned int ret;
    
    __asm("MRC p15, 0, %0, c0, c0, 5":"=r"(ret)::"memory");     
    
    if (ret & (1<<0)){
        return CPU1_IDX; 
    }else{
        return CPU0_IDX; 
    }
}

void isr_init(void)
{
    T_isr_list *pIsrList;
    int i = 0;
    
    unsigned int cpuIdx = cpu_getIntrIdx();
        
    
    if(isr_init_flag == 0)
    {
        for (i = 0; i < IRQ_SWITCH_TOTAL_CNT; i++){
            sIrqTab[i] = NO_ISR;
        }
        for (i = 0; i < FIQ_SWITCH_TOTAL_CNT; i++){
            sFiqTab[i] = NO_ISR;
        }
        isr_init_flag = 1;
    }
    
    i = 0;
    pIsrList = (T_isr_list *)(&__section_irq_table_start);        
    
    while (pIsrList < (T_isr_list*)(&__section_irq_table_end)){    
        if ((pIsrList->attr & ISR_ATTR_SWITCH) &&(pIsrList->isrName < IRQ_SWITCH_TOTAL_CNT)){   
                //  if(cpuIdx == (((pIsrList->attr&ISR_ATTR_CORE_BIT_MASK) >> 31)+1))
                {
                    sIrqTab[pIsrList->isrName] = i;
                    hprintf(TSENV, "\nno %d,irq %d: %s,isEdge: %d",i,pIsrList->isrName,pIsrList->description,IS_EDGE(pIsrList->attr)); 
                    cpu_gic_config_irq(pIsrList->isrName,IS_EDGE(pIsrList->attr),cpuIdx);
                }    
                //cpu_gicd_set_enable(pIsrList->isrName);
        }
        
        i++;
        pIsrList++;
    }    
    
    
    i = 0;
    pIsrList = (T_isr_list *)(&__section_fiq_table_start);        
    
    while (pIsrList < (T_isr_list*)(&__section_fiq_table_end)){    
        if ((pIsrList->attr & ISR_ATTR_SWITCH) && (pIsrList->isrName < FIQ_SWITCH_TOTAL_CNT)){
                // if(cpuIdx == (((pIsrList->attr&ISR_ATTR_CORE_BIT_MASK) >> 31)+1))
                {
                    sFiqTab[pIsrList->isrName] = i;
                    hprintf(TSENV, "\nno %d,fiq %d: %s,isEdge: %d",i,pIsrList->isrName,pIsrList->description,IS_EDGE(pIsrList->attr)); 
                    cpu_gic_config_fiq(pIsrList->isrName,IS_EDGE(pIsrList->attr),cpuIdx);
                }
        }
        
        i++;
        pIsrList++;
    }        
    
    cpu_gic_config_nonsecure();  
}

//flag for test
volatile int irqFlag = 0;
void irq_enter (void){
    T_isr_list *pIsrList;    
    int intrNum;
    unsigned int data;
    
    irqFlag = 1;
    //hprintf(TSENV, "\nirq comming");    
    data = cpu_gicc_get_aiar();
    //cpu_gicd_clear_enable(data);

    //hprintf(TSENV, "\nirq aiar %d",data);    
    //hprintf(TSENV, "\niar %d",cpu_gicc_get_iar());    
    
    intrNum = data&0x3ff;
    if (intrNum == 1022){
        putc_user('p');
        putc_user('r');
        putc_user('m');
        putc_user('t');
        return;
    }else if (intrNum == 1023){
        //source disappear
        putc_user('1');
        putc_user('0');
        putc_user('2');
        putc_user('3');
        return;    
    }else if ((sIrqTab[intrNum] != NO_ISR) && (intrNum < IRQ_SWITCH_TOTAL_CNT)){
        pIsrList = (T_isr_list *)(&__section_irq_table_start);
        pIsrList += sIrqTab[intrNum];
        pIsrList->isrFn(pIsrList->para);
    }else{
        hprintf(TSENV, "\nirq %d not register",intrNum);
        getc_user();
        hprintf(TSENV, "\niar %d",cpu_gicc_get_iar());
        while(1);
    }    
    
    //hprintf(TSENV, "\nbefore set aeoir");
    cpu_gicc_set_aeoir(data);       
    //next delay is for test prmt
    //delaySoft(1000);    
    //hprintf(TSENV, "\nexit irq");
    irqFlag = 0;
}

void fiq_enter (void){         
    T_isr_list *pIsrList;    
    int intrNum;
    unsigned int data;
    
    if (irqFlag){
        hprintf(TSENV, "\n!!!!prmt form irq!!!!");  
    }
    hprintf(TSENV, "\nfiq comming");    
    //getc_user();
    data = cpu_gicc_get_iar();    
    hprintf(TSENV, "\nfiq iar %d",data);    
    //hprintf(TSENV, "\naiar %d",cpu_gicc_get_aiar());        
    
    intrNum = data&0x3ff;
    if (intrNum == 1022){
        putc_user('p');
        putc_user('r');
        putc_user('m');
        putc_user('t');
        return;
    }else if (intrNum == 1023){
        //source disappear
        putc_user('1');
        putc_user('0');
        putc_user('2');
        putc_user('3');
        return;
    }else if ((sFiqTab[intrNum] != NO_ISR) && (intrNum < FIQ_SWITCH_TOTAL_CNT)){
        hprintf(TSENV, "\nfiq handle");    
         pIsrList = (T_isr_list *)(&__section_fiq_table_start);
         pIsrList += sFiqTab[intrNum];
         pIsrList->isrFn(pIsrList->para);
    }else{
         hprintf(TSENV, "\nFiq %d not register",intrNum);
         hprintf(TSENV, "\naiar %d",cpu_gicc_get_aiar());
         while(1);
    }    
    
    cpu_gicc_set_eoir(data);    
    hprintf(TSENV, "\nexit fiq");
}


void swi_main (void){
    hprintf(TSENV, "\nswi comming");    
}



static void cpu_StatueReport(void)
{ 
    int ret;

    //putc_user('1');    
    __asm("MRS %0,CPSR":"=r"(ret)::"memory");     
    //putc_user('2');
    hprintf(TSENV, "\n\rCPSR = 0x%x",ret); 
}



static void (*dAbrtCb)(void) = NULL;

void dAbrtSetCb(void (*CbFn)(void)){    
    dAbrtCb = CbFn;
}
void dAbrtCleanCb(void){    
    dAbrtCb = NULL;
}

static unsigned int sLstLr = 0;
static unsigned int sRtyCnt = 0;
void dabort_main (unsigned int lr,unsigned int sp){
    unsigned int *pSP;
    hprintf(TSENV, "\ndata abort exception error");     
    hprintf(TSENV, "\nlr 0x%x, sp 0x%x",lr,sp);   
    cpu_StatueReport(); 
    r5AsynAbt_close();
    cpu_StatueReport(); 

    if (sLstLr == lr){
        hprintf(TSENV, "\nlr is same ,retry cnt %d",sRtyCnt);     
        if (sRtyCnt > 0){
            sRtyCnt--;
            if (dAbrtCb){
                dAbrtCb();
            }            
        }else{
            hprintf(TSENV, "\nlr is same ,retry fail");     
            pSP = (unsigned int *)(sp);
            pSP += 13;
            if (*pSP == lr){
                 hprintf(TSENV, "\nfind lr,ignore");     
                *pSP += 4;
            }else{
                hprintf(TSENV, "\nlr?=0x%x",*pSP);     
            }
            sRtyCnt = 1;
        }
    }else{
        hprintf(TSENV, "\nfirst comming ,retry");     
        
        sLstLr = lr;
        sRtyCnt = 2;
        if (dAbrtCb){
            dAbrtCb();
        }
    }    

    r5AsynAbt_open();
    cpu_StatueReport(); 
}

void pabort_main (void){
    hprintf(TSENV, "\nprefech abort exception error");     
}


void undef_main (void){
    hprintf(TSENV, "\nundef exception error");     
}

void tcm_openEccParity(void)
{    
    asm("MRC p15, 0, r1, c1, c0, 1"); //Read Auxiliary Register
    asm("BFC r1,#3, #3"); //ecc parity enable,force write throught,enabel hardware enable
    asm("ORR r1, r1, #0x1 <<25"); //atcm check enable

    asm("MRC p15, 0, r2, c15, c0, 0"); //second Auxiliary Register
    asm("ORR r2, r2, #0x1"); //enable RMW

    asm("DSB");  
    asm("MCR p15, 0, r2, c15, c0, 0"); // enabled second auxiliary config
    asm("MCR p15, 0, r1, c1, c0, 1"); // enabled auxiliary config
    asm("ISB");
}

static void cpu_report(unsigned long para)
{ 
    int ret;
    putc_user('1');    
    __asm("MRC p15, 0, %0, c0, c0, 5":"=r"(ret)::"memory");     
    putc_user('2');
    hprintf(TSENV, "\n\rMitiProc, affinity,c0,5 = 0x%x",ret); 
    if (ret & (1<<0)){
        hprintf(TSENV, "\n\rcpu 1"); 
    }else{
        hprintf(TSENV, "\n\rcpu 0"); 
    }

    putc_user('3');    
    __asm("MRC p15, 0, %0, c1, c0, 1":"=r"(ret)::"memory");     
   //  putc_user('p');
    hprintf(TSENV, "\n\rauxiliary c1,1 = 0x%x",ret); 
    if (ret & (1<<25)){
        hprintf(TSENV, "\n\rAtcm ecc open"); 
    }
    if ((ret & (0x7<<3)) == 0){
        hprintf(TSENV, "\n\recc open,write throught,hard recover"); 
    }

    putc_user('4');    
    __asm("MRC p15, 0, %0, c15, c0, 0":"=r"(ret)::"memory");     
   //  putc_user('p');
    hprintf(TSENV, "\n\rsecond auxiliary c15,0 = 0x%x",ret); 
    if (ret & (1<<0)){
        hprintf(TSENV, "\n\rRMW,64 bit store open"); 
    }

    cpu_StatueReport();
 }

void envInit(void)
{    
    unsigned int uartBase;
    unsigned int temp,temp1;
    uint32_t reg_temp;

    /*set lsp block reset bit*/
    REG32(SW_CRM_CSR_BASE_ADDR) = 0xABCD1234;
    REG_BIT_SET32((SW_CRM_CSR_BASE_ADDR + SW_RST_OFFSET), BIT13);
    reg_temp = REG32_READ((SW_CRM_CSR_BASE_ADDR+SW_RST_OFFSET));
    reg_temp |=0xFFFFFFC1;
    REG32(SW_CRM_CSR_BASE_ADDR+SW_RST_OFFSET) =  reg_temp;
    REG32_WRITE(SW_CRM_CSR_BASE_ADDR+ETH_RST_OFFSET,0xFFFFFFFF);

    REG32(SW_SYS_CTRL_ADDR) = 0xABCD1234;

#if 0
    REG32(0xc0034ff0) = 0xABCD1234;
    //uart0 pinmux
    temp = REG32(0xc0034014);
    temp &= ~(0x3f<<12);//rts cts
    temp |= 9<<12;
    temp &= ~(0x7<<27);//txd
    REG32(0xc0034014) = temp;
    temp = REG32(0xc0034018);
    temp &= ~(0x7<<0);//rxd
    REG32(0xc0034018) = temp;

    //uart1 pinmux
    temp = REG32(0xc0034014);
    temp &= ~(0x3f<<0);//rts cts
    temp &= ~(0x3f<<21);//txd rxd
    temp |= 0x12<<0;
    temp |= 0x12<<21;
    REG32(0xc0034014) = temp;
    REG32(0xc003400c) = 0x3f300000;
#endif

    //realtime uart 0-3 mux 0
    REG32_WRITE(0xd1035000 + 0xff0 , 0xabcd1234);
    REG_BIT_CLEAR32(0xd1035000 + 0xc , 0x3ffffe00);
    REG_BIT_CLEAR32(0xd1035000 + 0x10 , BIT(0) | BIT(1) | BIT(2) ); 

    uartBase = RT_UART1_BASE_ADDR;
    /**********buadraet and init*****/
#ifdef UART_DEBUG_RT2
    uart_print_init(BUAD_RATE_115200 , uartBase , BUAD_RATE_MAIN_CLK_25M);
#endif

    //test putc_user
    putc_user('S');
    putc_user('W');
    putc_user('2');
    putc_user('\r');
    putc_user('\n');
}    

u32 cpu1_cnt = 0;
#if (!defined (moudle_test_msgbox) && !defined (moudle_test_msgbx))
// extern void msgbox_node_all_test(unsigned int para);
#endif
void cpu1_main(void)
{
    while (isr_init_flag == 0)
    {
        ;
    }
    envInit();
    isr_init();
    r5intr_open();
    cpu1_cnt++;
#if (!defined (moudle_test_msgbox) && !defined (moudle_test_msgbx))
    // msgbox_node_all_test(0);
#endif
    while (1)
    {
        cpu1_cnt++;
        //hprintf(TSENV, "cpu1_main=%d\r\n", cpu1_cnt);
        delaySoft(10000);
    }
}


void switch_irq_enable(void) 
{
	IRQ_ENABLE(SW_INTR_NPU_INTR0);
	IRQ_ENABLE(SW_INTR_NPU_INTR18);
    IRQ_ENABLE(SW_INTR_EPP_XGMAC_SBD_SFTY_UE_INTR);
    IRQ_ENABLE(SW_INTR_EPP_XGMAC_SBD_SFTY_RE_INTR);
}


void cache_enable(void){    
    __asm__("MRC p15, 0, r1, c1, c0, 0"); //Read System Control Register configuration data
    __asm__("ORR r1, r1, #0x1 <<12"); //instruction cache enable
    __asm__("ORR r1, r1, #0x1 <<2"); //data cache enable
    __asm__("DSB"); // 
    __asm__("MCR p15, 0, r0, c15, c5, 0"); // Invalidate entire data cache
    __asm__("MCR p15, 0, r0, c7, c5, 0"); // Invalidate entire instruction cache
    __asm__("MCR p15, 0, r1, c1, c0, 0"); // enabled cache RAMs
    __asm__("ISB"); //
}

//int main(int para1, int para2)
void firmware_main(void);
extern void sw_core0_wdt_init(void);
extern u32 ipc_trans_layer_start(const uint8_t endid, uint8_t role);
int cpu0_main(void)
{    
    void *p;

    // Mcu_Bst_InitClock();
#if defined(CORE0_FLAG) || defined(CORE1_FLAG)
    u8 pid = (REG32_READ(MSG_BOX01_ADDR) & 0xFF);
#elif defined(CORE2_FLAG) || defined(CORE3_FLAG)
    u8 pid = (REG32_READ(MSG_BOX23_ADDR) & 0xFF);
#elif defined(CORE4_FLAG) || defined(CORE5_FLAG)
    u8 pid = (REG32_READ(MSG_BOX45_ADDR) & 0xFF);
#else
#error "CORE[x]_FLAG need define, x=0/1/2"
#endif
    envInit();
     int ret = ipc_trans_layer_start(0, 0);
     if (ret != 0)
        hprintf(TSENV, "start switch 5 fail, ret %d\n", ret);
    REG32_WRITE(0x217a0000, 0xFFFFFFFF);
    //cache_enable();
    putc_user('c');
    //tcm_openEccParity();
    closePrintf();
    isr_init();
    openPrintf();
    
    //cpu_StatueReport(); 
    r5intr_open();

	switch_irq_enable();

    //cpu_StatueReport(); 
    //r5AsynAbt_open();
    //cpu_StatueReport(); 
    //sync_uart_init(); 
    //cpu_report(0);
    hprintf(TSENV, "\r\n"
                   "-----------------\r\n"
                   "| BST HVTE[0x%x] |\r\n"
                   "-----------------\r\n",
            pid);

    hprintf(TSENV , "%s" , s_bst_ver_info);

    sw_core0_wdt_init();
    firmware_main();

#if 1
    cmd_main();
#else
    auto_main();
#endif
     
    return 0;
}